<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <script>
      // 动物的属性：物种名 腿的数量 食物
      function Animal(type, legs, food) {
        // this为正在构建的动物实例animal
        this.type = type;
        this.legs = legs;
        this.food = food;
      }

      /* 动物的方法：吃 死 */
      Animal.prototype.eat = function () {
        // this是调用xxx.eat()的主语xxx
        console.log(`${this.legs}条腿的${this.type}正在浪费${this.food}`);
      };

      Animal.prototype.goDie = function () {
        console.log(`${this.type}眼一闭腿一蹬回去报道了`);
      };

      //   const animal = new Animal("狗狗", 4, "骨头");
      //   animal.eat();//eat方法中的this就是当前的animal实例
      //   animal.goDie();
    </script>

    <!-- 让Person类继承Animal类（不费一枪一弹免费得到Animal的全部属性与方法） -->
    <script>
      function Person(name, age) {
        /* 这里的this都是正在构建的Person实例——丰哥 */

        //如果就这么调用 作为一个普通的函数调用 其主语隐式的是window
        // Animal("人", 2, "大米饭")

        /* 继承属性：调用父类构造方法，绑定其中的this为当前正在构建的Person实例 其余属性值依次传入 */
        // 在调用Animal("人", 2, "大米饭")时候 将其this绑定为正在构建的“丰哥”对象
        Animal.call(this, "人", 2, "大米饭"); //这里的一行相当于下面的三行
        // this.type = "人";
        // this.legs = 2;
        // this.food = "大米饭";

        /* Person类独有的属性 */
        this.name = name;
        this.age = age;
      }

      /* 继承Animal的所有方法 */
      /* 攻略：抓一只Animal实例（肯定会eat+goDie）当Person类的老婆（原型） */
      Person.prototype = new Animal();

      /* Person类独有的方法 */
      // 通过Person的原型对象共享think方法给所有实例
      Person.prototype.think = function () {
        console.log(`${this.name}正在使用它的大脑而不是大腿思考`);
      };

      // 构建一个Person实例
      const fg = new Person("丰哥", 60);
      console.log(fg);
      fg.think(); //think中的this就是fg
      fg.eat();
      fg.goDie();
    </script>

    <!-- 让学生类Student继承人Person -->
    <script>
      // major=专业
      function Student(name, age, major) {
        // 从Person继承其所有属性：调用父类构造函数+绑定其this为当前正在构建的学生实例
        Person.call(this, name, age);

        this.major = major;
      }
      // 从Person继承其所有方法
      // 攻略：抓一只Person实例（会think+eat+goDie）给Student当老婆（给所有的学生实例当妈咪）
      Student.prototype = new Person("孙猴子的妈", 500);
      // 学生独有方法：学习study
      Student.prototype.study = function () {
        console.log(`${this.name}默默打开了Bilibili学习${this.major}`);
      };
      const s = new Student("孙猴子", 18, "H5");
      s.study(); //study中的this即为s

      // Person会的学生会（Student和Person父子类关系）
      s.think();

      // 动物会的学生也会（Student和Animal祖孙类关系）
      s.eat();
      s.goDie();
      console.log("s.toString()", s.toString());
      // s.printMoney()

      // 打印孙猴子（关注其原型链）
      console.log(s);
    </script>
  </body>
</html>
